#ifndef OPTIONSAPI_H
#define OPTIONSAPI_H

#include "CoreDBAPI.h"

#define TABLE_FIELD_AMOUNT 4

int tableFieldsWidth[TABLE_FIELD_AMOUNT+1] = {0}; //Plus Null terminating char
char *firstField = NULL;
int tableWidth = 0;

void setFirstField(char *nextField){
	if( !firstField )
		free(firstField);
	firstField = NULL;

	firstField = (char*)malloc((strlen(nextField)+1)*sizeof(char));
	assertMem(firstField);

	strcpy(firstField, nextField);
}

int getTableFieldWidth(char *string){
	if( strcmp("Server IP", string) == 0 )
		return (strlen("Server IP") > SERVER_ADDR_LENGTH)? strlen("Server IP") : SERVER_ADDR_LENGTH;
	else if( strcmp("Service Name", string) == 0 )
		return (strlen("Service Name") > SERVICE_NAME_LENGTH)? strlen("Service Name") : SERVICE_NAME_LENGTH;
	else if( strcmp("Service Version", string) == 0 )
		return (strlen("Service Version") > SERVICE_VERSION_LENGTH)? strlen("Service Version") : SERVICE_VERSION_LENGTH;
	else if( strcmp("Latest Version", string) == 0 )
		return (strlen("Latest Version") > SERVICE_VERSION_LENGTH)? strlen("Latest Version") : SERVICE_VERSION_LENGTH;
	else if( strcmp("Username", string) == 0 )
		return (strlen("Username") > USERNAME_LENGTH)? strlen("Username") : USERNAME_LENGTH;
	else if( strcmp("Operation", string) == 0 )
		return (strlen("Operation") > OPERATION_LENGTH)? strlen("Operation") : OPERATION_LENGTH;
	else if( strcmp("Message Inbox", string) == 0 )
		return 32;
	else
		return strlen(string);
}

void printTableLines(){
	int i = 0, amount = 0;
	
	while( tableFieldsWidth[i++] )
		amount ++;
	for( i = 0 ; i < tableWidth+amount+1 ; i++ )
		fprintf(stdout, "-");
	fprintf(stdout, "\n");

}

void printTableHead(int amount, ... ){
	va_list vl;
	char **fieldsArr;
	char *nextField;
	int i = 0, j = 0;

	tableWidth = 0;
	va_start(vl, amount);
	fieldsArr = (char**)malloc(TABLE_FIELD_AMOUNT*sizeof(char*));
	assertMem(fieldsArr );

	if( amount > TABLE_FIELD_AMOUNT ){
		changeColorRed();
		fprintf(stderr, "Table only supports %d columns.\n", TABLE_FIELD_AMOUNT);
		changeColorDefault();
		amount = TABLE_FIELD_AMOUNT;
	}

	for( i = 0 ; i < amount ; i++ ){
		nextField = va_arg(vl, char*);
		fieldsArr[i] = nextField;
		tableFieldsWidth[i] = getTableFieldWidth(nextField);
		tableWidth += tableFieldsWidth[i] + 2;
	}

	printTableLines();
	for( i = 0 ; i < amount ; i++){
		fprintf(stdout, "|");
		changeColorGreen();
		fprintf(stdout, "%s%-*s%s"," ", tableFieldsWidth[i], fieldsArr[i], " ");
		changeColorDefault();
	}
	fprintf(stdout, "|\n");

	va_end(vl);
	free(fieldsArr);
}

void printTableBody(int amount, ... ){
	va_list vl;
	char **fieldsArr;
	char *nextField;
	int i = 0, isAtFirstField = 0, resend = 0;

	va_start(vl, amount);
	fieldsArr = (char**)malloc(TABLE_FIELD_AMOUNT*sizeof(char*));
	assertMem( fieldsArr );

	if( amount > TABLE_FIELD_AMOUNT )
		amount = TABLE_FIELD_AMOUNT;

	for( i = 0 ; i < amount ; i++ ){
		nextField = va_arg(vl, char*);
		fieldsArr[i] = nextField;
	}

	if( firstField && strcmp(firstField, fieldsArr[0]) == 0)
		isAtFirstField = 1;
	else
		setFirstField(fieldsArr[0]);
	
	if( !isAtFirstField )
		printTableLines();

	fprintf(stdout, "|");
	for( i = 0 ; i < amount ; i++)
		fprintf(stdout, " %-*.*s %s",  tableFieldsWidth[i], tableFieldsWidth[i], (isAtFirstField && i==0)?" ":fieldsArr[i], ( i == amount-1)?"|":" ");
	fprintf(stdout, "\n");

	va_end(vl);

	for( i = 0 ; i < amount ; i++ )
	{
		if( strlen(fieldsArr[i]) > tableFieldsWidth[i] ){
			fieldsArr[i] = fieldsArr[i] + tableFieldsWidth[i];
			resend = 1;
		}
	}

	i = TABLE_FIELD_AMOUNT;
	if( resend )
		printTableBody(amount, fieldsArr[0], fieldsArr[1], fieldsArr[2], fieldsArr[3], fieldsArr[(4>i)?i-1:4], fieldsArr[(5>i)?i-1:5] );

	free(fieldsArr);
}

void printTableBottom(){
	int i = 0;
	
	printTableLines();

	for( i = 0 ; i < TABLE_FIELD_AMOUNT ; i++ )
		tableFieldsWidth[i] = 0;
	firstField = NULL;
}

#endif